/*
 * @Author: LOOP oo
 * @Date: 2025-03-29 19:10:23
 * @LastEditors: Joel
 * @LastEditTime: 2025-03-29 19:40:00
 * @FilePath: \loop2\usr\src\user_timer.c
 * @Description: 定时器14
 * 
 * Copyright (c) 2025 by LOOP oo, All Rights Reserved. 
 */

/* 包含头文件代码 */
#include "user_timer.h"


/*******************************************************************************
 * Definitions
 ******************************************************************************/

/* 私有(仅本源文件内使用)宏、枚举、结构体的定义 */
#define TIMER_MAX 6

typedef struct _userTimer_{
    // 使能定时器
    uint8_t en; 
    // 进入中断后的计数值
    uint32_t timeCntMs;
    // 计时关阈值
    uint32_t timeoutMs;
    // 回调函数的形参
    void *arg;
    // 回调函数
    void (*cb)(void*);
}userTimer_t;
static userTimer_t userTimer[TIMER_MAX];

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/* 内部函数(即 static 修饰)的声明 */


/*******************************************************************************
 * Variables
 ******************************************************************************/

/* 所有全局变量(外部，静态，常量，指针)的定义 */


/*******************************************************************************
 * Code
 ******************************************************************************/
extern uint32_t SystemCoreClock ;
/* 所有函数(外部，内部)的定义 */
static void User_Timer_Hw_Init(void){
  /*set TIM14 */
  LL_TIM_InitTypeDef TIM14CountInit = {0};
	
  LL_APB1_GRP2_EnableClock(RCC_APBENR2_TIM14EN);
  
  TIM14CountInit.ClockDivision       = LL_TIM_CLOCKDIVISION_DIV1; /*  */
  TIM14CountInit.CounterMode         = LL_TIM_COUNTERMODE_UP;     /*  */
  TIM14CountInit.Prescaler           = TIMER14_PRESCALER;                    /*  */
  TIM14CountInit.Autoreload          = (SystemCoreClock/TIMER14_PRESCALER/BASE_TIME14_MS)-1;                    /* 1000 */
  TIM14CountInit.RepetitionCounter   = 0;                         /* 0 */
  
  /* TIM14 */
  LL_TIM_Init(TIM14,&TIM14CountInit);
  
  /* UPDATA */
  LL_TIM_EnableIT_UPDATE(TIM14);
  
  /* TIM14 */
  LL_TIM_EnableCounter(TIM14);
  
  /* UPDATA */
  NVIC_EnableIRQ(TIM14_IRQn);
  NVIC_SetPriority(TIM14_IRQn,0);
}

/**
 * @brief  This function handles TIMERx interrupt request.
 * @param  None
 * @retval None
 */
void TIM14_IRQHandler(void)
{
    int i = 0;
    if(LL_TIM_IsActiveFlag_UPDATE(TIM14) && LL_TIM_IsEnabledIT_UPDATE(TIM14))
    {
      LL_TIM_ClearFlag_UPDATE(TIM14);
      for(i=0;i<TIMER_MAX;i++){
        if(userTimer[i].en&&userTimer[i].cb!=NULL){
            userTimer[i].timeCntMs++;
            if(userTimer[i].timeCntMs >= userTimer[i].timeoutMs){
                userTimer[i].timeCntMs = 0;
                userTimer[i].cb(userTimer[i].arg);
            }
        }else{
            userTimer[i].timeCntMs = 0;
        }
    }
    }
}


void User_Timer_Init(void){
    printf("User_Timer_Init...\r\n");
    int i = 0;
    User_Timer_Hw_Init();
    for(i=0;i<TIMER_MAX;i++){
        userTimer[i].en = 0;
        userTimer[i].timeCntMs = 0;
        userTimer[i].timeoutMs = 0;
        userTimer[i].arg = NULL;
        userTimer[i].cb = NULL;
    }
}

void User_Timer_Config(uint8_t timerId,uint32_t timeoutMs,void (*cb)(void *),void *arg){
    userTimer[timerId].cb = cb;
    userTimer[timerId].arg = arg;
    userTimer[timerId].timeoutMs = timeoutMs;
}

void User_Timer_Start(uint8_t timerId){
    userTimer[timerId].en = 1;
}

void User_Timer_Stop(uint8_t timerId){
    userTimer[timerId].en = 0;
}

void User_Timer_Clear(uint8_t timerId){
    userTimer[timerId].en = 0;
    userTimer[timerId].cb = NULL;
    userTimer[timerId].arg = NULL;
    userTimer[timerId].timeoutMs = 0;
    userTimer[timerId].timeCntMs = 0;
}
/* el psy congroo */
